/******************** (C) COPYRIGHT 2018 merafour ********************
* Author             : 冷月追风@merafour.blog.163.com
* Version            : V1.0.0
* Date               : 8/1/2019
* Description        : 语言转换.
********************************************************************************
* merafour.blog.163.com
* merafour@163.com
* github.com/Merafour
*******************************************************************************/
#include "qitranslator.h"
#include "string.h"
#include <QSettings>
#include <QDebug>
#include <stdio.h>
#include <string.h>
#include "menu/about.h"

const char QiTranslator::cutover_file_path[32] = "Language1.txt";

QiTranslator::QiTranslator(QString _objName, const char** _table, const uint16_t _size, QObject *parent) : QObject(parent), \
    objName(_objName), translator_table(_table), translator_size(_size)
{
    json_obj_root = nullptr;
}

void QiTranslator::load()
{
    const char *object;
    //const char *string;
    uint16_t i;
    QString text;
    char* imagebyte;
    cJSON* item=nullptr;
    uint8_t wflag=0; // 写入标志
    cJSON* root;
    cJSON* objroot;
    imagebyte=open(cutover_file_path);
    if(nullptr==imagebyte)
    {
        imagebyte=open(cutover_file_path);
    }
    if(nullptr==imagebyte)
    {
        qDebug() << "转换文件无法打开" ;
        return;
    }
    //qDebug("imagebyte: %08X, %08X", imagebyte, imagebyte[0]);
    //qDebug("imagebyte: %s", imagebyte);
    root = cJSON_Parse(imagebyte);
    if(nullptr == root)
    {
        create_cutover(cutover_file_path);  // 文件为空则创建
        if(nullptr != imagebyte) free(imagebyte);
        imagebyte=open(cutover_file_path);
        if(nullptr==imagebyte)
        {
            qDebug() << "转换文件无法打开" ;
            return;
        }
        root = cJSON_Parse(imagebyte);
        goto bad;
    }
    objroot = cJSON_GetObjectItem( root , objName.toLocal8Bit().data());
    if(nullptr==objroot ) // 节点不存在则创建
    {
        objroot =  cJSON_CreateObject();
        cJSON_AddItemToObject(root, objName.toLocal8Bit().data(), objroot);
    }
    for(i=0; i<translator_size; i++)
    {
        text = QString::fromUtf8(translator_table[i]);
        if(text.isEmpty()) continue;
        object = text.toLocal8Bit().data();
        item = cJSON_GetObjectItem( objroot , object);
        if((nullptr==item) || (0>=strlen(item->valuestring))) // 无当前项
        {
            cJSON_AddItemToObject(objroot, object, cJSON_CreateString(translator_table[i]));
            wflag = 1;
            continue;
        }
    }
    if(wflag)
    {
        char* json_str;
        json_str = cJSON_Print(root);
        savecJSON(cutover_file_path, json_str);
        free(json_str);
    }
    json_obj_root = objroot;
    json_root = root;

bad:
    if(nullptr != imagebyte) free(imagebyte);
    //if(nullptr != root) cJSON_Delete(root);
}

const QString QiTranslator::cutover(const QString _text)
{
    QString _language;
    cJSON* item=nullptr;
    const char *object;
    object = _text.toLocal8Bit().data();
    //qDebug() << "object" ;
    item = cJSON_GetObjectItem(json_obj_root , object);
    if((nullptr != item) && (strlen(item->valuestring) > 0))
    {
        _language = QString::fromUtf8(item->valuestring);
        return  _language;
    }
    return _text;
}

char* QiTranslator::open(const char *path)
{
    size_t _size=0;
    size_t r_size=0;
    char* imagebyte=nullptr;

    FILE *fp = nullptr;
    //qDebug() << "open cutover file" ;
    fp = fopen(path, "rb");
    if(nullptr == fp)
    {
        qDebug() << "Unable to open" << QString::fromLocal8Bit(path);
        create_cutover(path);  // 文件不存在则创建
        goto bad;
    }
    fseek(fp, 0, SEEK_END);
    _size = static_cast<size_t>(ftell(fp));
    if(0!=fseek(fp, 0, SEEK_SET))
    {
        qDebug() << "Unable to SET" << QString::fromLocal8Bit(path);
        goto bad;
    }
    //qDebug() << "_size:" << _size;
    r_size = _size - _size%1024+2048;
    //if(nullptr == imagebyte) imagebyte = (char*)malloc(r_size);
    if(nullptr == imagebyte) imagebyte = reinterpret_cast<char *>(malloc(r_size));
    if(nullptr == imagebyte)
    {
        qDebug() << "malloc space fail!";
        goto bad;
    }
    memset(imagebyte, 0x00, r_size);
    r_size = fread(imagebyte, 1, _size, fp);
    //qDebug() << "r_size:" << r_size;
    if(_size != r_size)
    {
        qDebug() << "read music fail" ;
        goto bad;
    }
    fclose(fp);
    return imagebyte;
bad:
    if(nullptr != fp) fclose(fp);
    return nullptr;
}

int QiTranslator::create_cutover(const char *path)
{
    QString item;
    uint16_t i;
    cJSON* root =  cJSON_CreateObject();
    cJSON* objroot =  cJSON_CreateObject();
    char* json_str;

    cJSON_AddItemToObject(root, "IPMB Assistant", cJSON_CreateString(About::version().toLocal8Bit().constData()));//根节点下添加
    cJSON_AddItemToObject(root, "Description.en", cJSON_CreateString("Language Translator File"));//根节点下添加
    cJSON_AddItemToObject(root, "Description.cn", cJSON_CreateString("语言转换文件"));

    cJSON_AddItemToObject(root, objName.toLocal8Bit().data(), objroot);
    for(i=0; i<translator_size; i++)
    {
        item = QString::fromUtf8(translator_table[i]);
        if(item.isEmpty()) continue;
        //cJSON_AddItemToObject(root, (objName+item).toLocal8Bit().data(), cJSON_CreateString(translator_text[i]));
        cJSON_AddItemToObject(objroot, item.toLocal8Bit().data(), cJSON_CreateString(translator_table[i]));
    }
    json_str = cJSON_Print(root);
    //json_str = cJSON_PrintUnformatted(root);
    savecJSON(path, json_str);

//bad:
    cJSON_Delete(root);
    free(json_str);
    return 0;
}

int QiTranslator::savecJSON(const char *path, const char* json_str)
{
    size_t _size=0;
    size_t w_size=0;
    FILE* fp = nullptr;

    fp = fopen(path, "w+");
    if(nullptr == fp)
    {
        qDebug() << "Unable to open" << QString::fromLocal8Bit(path);
        goto bad;
    }
    if(0!=fseek(fp, 0, SEEK_SET))
    {
        qDebug() << "Unable to SET" << QString::fromLocal8Bit(path);
        goto bad;
    }
    _size = strlen(json_str);
    //qDebug() << "json size:" << _size;
    w_size = fwrite(json_str, 1, _size, fp);
    //qDebug() << "w_size:" << w_size;
    if(_size != w_size)
    {
        qDebug() << "write cJSON fail" ;
        goto bad;
    }
    fclose(fp);
    return 0;

bad:
    if(nullptr != fp) fclose(fp);
    return -1;
}
